package controllers;

import play.*;
import play.mvc.*;

import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.*;

import jpl.Atom;
import jpl.JPL;
import jpl.Query;
import jpl.Term;

import models.*;

import com.google.gdata.client.calendar.CalendarQuery;
import com.google.gdata.client.calendar.CalendarService;
import com.google.gdata.client.spreadsheet.SpreadsheetService;
import com.google.gdata.data.DateTime;
import com.google.gdata.data.Feed;
import com.google.gdata.data.PlainTextConstruct;
import com.google.gdata.data.calendar.CalendarEventEntry;
import com.google.gdata.data.calendar.CalendarEventFeed;
import com.google.gdata.data.extensions.When;
import com.google.gdata.data.spreadsheet.ListEntry;
import com.google.gdata.data.spreadsheet.ListFeed;
import com.google.gdata.data.spreadsheet.SpreadsheetEntry;
import com.google.gdata.data.spreadsheet.SpreadsheetFeed;
import com.google.gdata.data.spreadsheet.Worksheet;
import com.google.gdata.data.spreadsheet.WorksheetEntry;
import com.google.gdata.model.atom.Link;
import com.google.gdata.util.AuthenticationException;
import com.google.gdata.util.ServiceException;

public class Application extends Controller {
	public static SpreadsheetService myService = new SpreadsheetService("My Application");
	public static CalendarService myService2 = new CalendarService("My Application");
	public static List<SpreadsheetEntry> entries = new ArrayList<SpreadsheetEntry>();
	public static SpreadsheetEntry chosenEntry = new SpreadsheetEntry();
	public static String username="";
    public static void index(String Username, String Password) {
    	String message;
    	if(Username == null || Password == null)
    		render();
    	if(Username.equals("") || Password.equals("")){
    		message = "Please Enter both your Username and Password";
    		render(message);
    	}
    	else{
              if(myService!=null)
				try {
					username=Username;
					myService.setUserCredentials(Username, Password);
					myService2.setUserCredentials(Username, Password);
					myService.setConnectTimeout(10000000);
					myService2.setConnectTimeout(10000000);
				} catch (AuthenticationException e) {
					// TODO Auto-generated catch block
					message = "Incorrect Username or Password";
					render(message);
				}
//			System.out.println("here before submit");
//			session.put("Username", Username);
//			session.put("Password", Password);
    		submit();
    	}
    } 
    
    public static void submit(){
		myService.setConnectTimeout(10000000);
		myService2.setConnectTimeout(10000000);
    	//    	System.out.println("here inside submit");
    	String chrInput="";
        List<SpreadsheetEntry> entries2 = null;
        try {
//    		SpreadsheetService myService = new SpreadsheetService("My Application");
//			myService.setUserCredentials(session.get("Username"), session.get("Password"));
            // Get a list of all entries
            URL metafeedUrl = new URL("http://spreadsheets.google.com/feeds/spreadsheets/private/full");
            System.out.println("Getting Spreadsheet entries...\n");
            SpreadsheetFeed resultFeed = myService.getFeed(metafeedUrl, SpreadsheetFeed.class);
            entries = resultFeed.getEntries();
            entries2 = entries;
          }
          catch(AuthenticationException e) {
            e.printStackTrace();
          }
          catch(MalformedURLException e) {
            e.printStackTrace();
          }
          catch(ServiceException e) {
            e.printStackTrace();
          }
          catch(IOException e) {
            e.printStackTrace();
          }

		render(chrInput, entries2);
    }
    
    public static void entry(String name){
		myService.setConnectTimeout(10000000);
		myService2.setConnectTimeout(10000000);
		System.out.println("Inside Entry");
    	String link = "";
    	for(int i =0 ; i < entries.size() ; i++){
    		SpreadsheetEntry entry = entries.get(i);
    		if(entry.getTitle().getPlainText().equals(name)){
    			chosenEntry = entry;
    			link = entry.getHtmlLink().getHref();
    			try {
					List<WorksheetEntry> worksheets = entry.getWorksheets();
					render(link, worksheets, name);
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (ServiceException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
    			
    		}
    	}
    	render();
//        for(int i=0; i<entries.size(); i++) {
//            SpreadsheetEntry entry = entries.get(i);
//            // Choosing the SpreedSheet i am going to work on.
//            if(entry.getTitle().getPlainText().equals("Chr1")){
//          	  System.out.println("here we go CHR");
//          	  List <WorksheetEntry> worksheets = entry.getWorksheets();
//          	  com.google.gdata.data.Link test = entry.getHtmlLink();
//          	  System.out.println("here link" + test.getHref());
//          	  WorksheetEntry worksheet = worksheets.get(0);
//          	  listFeedurl = worksheet.getListFeedUrl();
//          	  ListFeed feed = myService.getFeed(listFeedurl, ListFeed.class);
//          	  boolean flag = true;
//          	  for (ListEntry lentry : feed.getEntries()) {
////          	    System.out.println(lentry.getTitle().getPlainText());
//          		if(flag)
//          			flag = false;
//          		else
//          			chrInput+=",";
//          		Set<String> tags = lentry.getCustomElements().getTags();
//          		String tag = lentry.getCustomElements().getValue("GPA");
//          		chrInput+= "gpa("+tag+")";
//          	    System.out.println(tag);
//          	    
//          	  }
//          	  chrInput+=", favrGPA(X, 15).";
//          	  System.out.println(chrInput);
//          	  // Extracting info using List-Based Feed.
//          	  break;
//            }
//          }
//          System.out.println("\nTotal Entries: "+entries.size());
//          JPL.init();
//
//  		Term consult_arg[] = { 
//  			new Atom( "/Users/Monayri/Documents/GUC - Engineering/Eclipse Workspace/ChrSS/src/test.pl" ) 
//  		};
//  		Query consult_query = 
//  			new Query( 
//  				"consult", 
//  				consult_arg );
//
//  		boolean consulted = consult_query.query();
//  		System.out.println("BT \n File consulted : " + consulted);
//  		Query X = new Query(chrInput);
//  		
//  		if ( !consulted ){
//  			System.err.println( "Consult failed" );
//  			System.exit( 1 );
//  		}
////  		X.open();
//  		System.out.println(X.oneSolution());
//  		String Solution =""+X.oneSolution();
//  		String [] split = Solution.split("=");
//  		String value = split[1];
//  		ListEntry newEntry = new ListEntry();
//  		newEntry.getCustomElements().setValueLocal("GPA", value);
//  		newEntry.getCustomElements().setValueLocal("Student", "Average");
//  		ListEntry insertedRow = myService.insert(listFeedurl, newEntry);

    }
    
    public static void getSheetColumns(int sheet, int column, int column2){
		myService.setConnectTimeout(10000000);
		myService2.setConnectTimeout(10000000);
    	System.out.println("Inside getSheetColumns   ");
  		URL listFeedurl = null;
    	try {
			List<WorksheetEntry> worksheets = chosenEntry.getWorksheets();
			WorksheetEntry worksheet = worksheets.get(sheet-1);
			listFeedurl = worksheet.getListFeedUrl();
			ListFeed feed = myService.getFeed(listFeedurl, ListFeed.class);
			List<ListEntry> lentry = feed.getEntries();
			if(!lentry.isEmpty()){
				Set<String> Tags = lentry.get(0).getCustomElements().getTags();
				List<String> Columns = new ArrayList<String>();
				int i =0;
				for(String Tag : Tags){
					if(i != column-1)
						Columns.add(Tag);
					i++;
				}
				System.out.println("LINE 200 ------------->" + Columns);
				if(Columns.size() !=0){
				for(i=0; i <Columns.size();i++){
					if(i == column2-1)
						Columns.remove(i);
				}
				}
				System.out.println("before rendering " + Columns);
				renderJSON(Columns);
			}
			
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ServiceException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
    }

    public static void getReasonings(){
    	List<String> reasonings = new ArrayList<String>();
    	reasonings.add("Average");
    	reasonings.add("Sum");
    	reasonings.add("Assign a task");
    	reasonings.add("Time management");
    	renderJSON(reasonings);
    }
    public static void performReasoning(int sheet, String column1, String column2, String column3, int reasoning){
		myService.setConnectTimeout(1000000000);
		myService2.setConnectTimeout(1000000000);
    	System.out.println("inside PERFORM " + sheet + " " +column1 + " " +column2 +" "+ reasoning);
    	List<List<String>> messages = new ArrayList<List<String>>();
    	switch(reasoning){
    	case 1:{
    		messages = performAverage(sheet, column1);
    	}break;
    	case 2:{
    		messages = performSum(sheet, column1);
    	}break;
    	case 3:{
    		messages = performAssignTask(sheet, column1, column2, column3);
    	}
    	}
    	
    	renderJSON(messages);
    }
    public static List<List<String>> performSum(int sheet, String column){
  		URL listFeedurl = null;
  		List<List<String>> messages = new ArrayList<List<String>>();
  		messages.add(new ArrayList<String>());
  		messages.add(new ArrayList<String>());
  		try {
			List<WorksheetEntry> worksheets = chosenEntry.getWorksheets();
			WorksheetEntry mySheet = worksheets.get(sheet-1);
			listFeedurl = mySheet.getListFeedUrl();
			ListFeed feed = myService.getFeed(listFeedurl, ListFeed.class);
			List<ListEntry> lentry = feed.getEntries();
			String chrInput="";
			boolean flag = true;
			int i =0;
			for (ListEntry entry : lentry) {
//    	   	 System.out.println(lentry.getTitle().getPlainText());
				
				Set<String> tags = entry.getCustomElements().getTags();
				String tag = entry.getCustomElements().getValue(column);
				if(tag!=null){
				if(flag)
					flag = false;
				else
					chrInput+=",";
				chrInput+= "input("+tag+")";
				i++;
				}
    	  }
    	  chrInput+=", finalSUM(X,"+i+").";
    	  System.out.println("chrInput = "+ chrInput);
          JPL.init();
			
			  		Term consult_arg[] = { 
			  			new Atom( "/Users/Monayri/Documents/GUC - Engineering/8th semester/CHR meets google Documents/Play Framework/CHR web application/ChrWeb/public/Prolog/sum.pl" ) 
			  		};
			  		Query consult_query = 
			  			new Query( 
			  				"consult", 
			  				consult_arg );
			
			  		boolean consulted = consult_query.query();
			  		Query X = new Query(chrInput);			  		
			  		if ( !consulted ){
			  			System.err.println( "Consult failed" );
			  			System.exit( 1 );
			  		}
			  		String Solution =""+X.oneSolution();
			  		String [] split = Solution.split("=");
			  		String value = split[1];
			  		String [] split2 = value.split("}");
			  		String sol = "sum = "+split2[0];
			  		ListEntry newEntry = new ListEntry();
			  		newEntry.getCustomElements().setValueLocal(column, sol);
			  		ListEntry insertedRow = myService.insert(listFeedurl, newEntry);
			  		messages.get(1).add("Reasoning performed correctly");

		} catch (Exception e) {
			messages.get(0).add( "An error Occured, make sure that the columns contain compatible types for sum");
			e.printStackTrace();
		}
		return messages;
    }
    
    public static List<List<String>> performAverage(int sheet, String column){
  		URL listFeedurl = null;
  		List<List<String>> messages = new ArrayList<List<String>>();
  		messages.add(new ArrayList<String>());
  		messages.add(new ArrayList<String>());
  		try {
			List<WorksheetEntry> worksheets = chosenEntry.getWorksheets();
			WorksheetEntry mySheet = worksheets.get(sheet-1);
			listFeedurl = mySheet.getListFeedUrl();
			ListFeed feed = myService.getFeed(listFeedurl, ListFeed.class);
			List<ListEntry> lentry = feed.getEntries();
			String chrInput="";
			boolean flag = true;
			int i =0;
			for (ListEntry entry : lentry) {				
				Set<String> tags = entry.getCustomElements().getTags();
				String tag = entry.getCustomElements().getValue(column);
				if(tag!=null){
				if(flag)
					flag = false;
				else
					chrInput+=",";
				chrInput+= "input("+tag+")";
				i++;
				}
    	  }
    	  chrInput+=", finalAVG(X,"+i+").";
    	  System.out.println("chrInput = "+ chrInput);
          JPL.init();
			
			  		Term consult_arg[] = { 
			  			new Atom( "/Users/Monayri/Documents/GUC - Engineering/8th semester/CHR meets google Documents/Play Framework/CHR web application/ChrWeb/public/Prolog/average.pl" ) 
			  		};
			  		Query consult_query = 
			  			new Query( 
			  				"consult", 
			  				consult_arg );
			
			  		boolean consulted = consult_query.query();
			  		Query X = new Query(chrInput);			  		
			  		if ( !consulted ){
			  			System.err.println( "Consult failed" );
			  			System.exit( 1 );
			  		}
			  		String Solution =""+X.oneSolution();
			  		String [] split = Solution.split("=");
			  		String value = split[1];
			  		String [] split2 = value.split("}");
			  		String sol = "average = "+split2[0];
			  		ListEntry newEntry = new ListEntry();
			  		newEntry.getCustomElements().setValueLocal(column, sol);
			  		ListEntry insertedRow = myService.insert(listFeedurl, newEntry);
			  		messages.get(1).add("Reasoning performed correctly");

		} catch (Exception e) {
			messages.get(0).add("An error Occured, make sure that the columns contain compatible types for Average");
			e.printStackTrace();
		}
		return messages;
    }
    public static List<List<String>> performAssignTask(int sheet, String column, String column2, String column3){
    	URL listFeedurl = null;
  		List<List<String>> messages = new ArrayList<List<String>>();
  		messages.add(new ArrayList<String>());
  		messages.add(new ArrayList<String>());
    	try {
    		URL feedUrl = new URL("https://www.google.com/calendar/feeds/default/private/full");
			List<WorksheetEntry> worksheets = chosenEntry.getWorksheets();
			WorksheetEntry mySheet = worksheets.get(sheet-1);
			listFeedurl = mySheet.getListFeedUrl();
			ListFeed feed = myService.getFeed(listFeedurl, ListFeed.class);
			List<ListEntry> lentry = feed.getEntries();
			for (ListEntry entry : lentry) {				
				String task = entry.getCustomElements().getValue(column);
				String startDate = entry.getCustomElements().getValue(column2);
				String endDate = entry.getCustomElements().getValue(column3);
				CalendarQuery myQuery = new CalendarQuery(feedUrl);
				myQuery.setMinimumStartTime(DateTime.parseDateTime(startDate+"+02:00"));
				myQuery.setMaximumStartTime(DateTime.parseDateTime(endDate+"+02:00"));
				CalendarEventFeed resultFeed = myService2.query(myQuery, CalendarEventFeed.class);
				System.out.println("ENTRIESSSSSSS "+resultFeed.getEntries());
				for(CalendarEventEntry cEntry : resultFeed.getEntries()){
					DateTime start = cEntry.getTimes().get(0).getStartTime();
					System.out.println(start.toString());
				}
				if(resultFeed.getEntries().size() == 0 ){
					URL postUrl = new URL("https://www.google.com/calendar/feeds/"+username+"@gmail.com/private/full");
						CalendarEventEntry myEntry = new CalendarEventEntry();
						myEntry.setTitle(new PlainTextConstruct(task));
						DateTime startTime = DateTime.parseDateTime(startDate);
						DateTime endTime = DateTime.parseDateTime(endDate);
						When eventTimes = new When();
						eventTimes.setStartTime(startTime);
						eventTimes.setEndTime(endTime);
						myEntry.addTime(eventTimes);
						CalendarEventEntry insertedEntry = myService2.insert(postUrl, myEntry);
						messages.get(1).add(task+" has been successfully added to your Calendar");
				}else{
					messages.get(0).add(task+" has a conflict with an event in your Calendar");
				}
    	  }
   			  		

		} catch (Exception e) {
			messages.get(0).add(0,"An error Occured, make sure that the columns contain compatible types for Assigning Tasks And the Date columns are in this Format 2011-04-20T01:00:00");
			e.printStackTrace();
		}
		return messages;

    }
}